package com.common.help.test12;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class NIOServer {

	int port;
	ServerSocketChannel server;
	Selector selector;
	ByteBuffer revice = ByteBuffer.allocate(1024);
	ByteBuffer send = ByteBuffer.allocate(1024);
	
	Map<SelectionKey,String> map = new HashMap<>();
	
	public NIOServer(int port) throws IOException{
		this.port = port;
		server = ServerSocketChannel.open();//类似修高速路
		server.socket().bind(new InetSocketAddress(port));//关卡打开  开始多路复用 
		server.configureBlocking(false);//非阻塞
		
		selector = Selector.open();//管家开始管理
		
		server.register(selector, SelectionKey.OP_ACCEPT);//老板准备完毕
		System.out.println("NIO服务端 启动完毕 监听端口:"+this.port);
	}
	
	
	public void listener() throws IOException{
		
		while(true){//轮询+
			
		int i = selector.select();//判断当前有没有 客户排队
		if(i == 0){continue;}
		
                      		Set<SelectionKey> selection = selector.selectedKeys();
		Iterator<SelectionKey> iterator = selection.iterator();
			
			while(iterator.hasNext()){
				SelectionKey key = iterator.next();
				//来一个处理
				process(key);
				//删除
				iterator.remove();
			}
		}
	}
	
	private void process(SelectionKey key) throws IOException {
		 //判断客户端是否有跟管家建立连接
		if(key.isAcceptable()){
			SocketChannel client = server.accept();
			client.configureBlocking(false);
			client.register(selector, SelectionKey.OP_READ);
			
		}//判断客户端是否有读的数据
		else if(key.isReadable()){
			revice.clear();
			SocketChannel client =(SocketChannel) key.channel();
			int len = client.read(revice);
			if(len>0){
				String s = new String(revice.array(),0,len);
				map.put(key, s);
				System.err.println("客户端消息："+s);
			}
			client.register(selector, SelectionKey.OP_WRITE);
		}//判断客户端是否有写的数据
		else if(key.isWritable()){
			if(!map.containsKey(key)){return;}
			SocketChannel client =(SocketChannel) key.channel();
			send.clear();
			send.put(new String(map.get(key)+",你好, 你的请求已处理").getBytes());
			send.flip();
			client.write(send);
			client.register(selector, SelectionKey.OP_READ);
		}
		
	}


	public static void main(String[] args) throws IOException {
		new NIOServer(8080).listener();
	}
}
